#pragma once
#include <iostream>
#include <string>
#include <pthread.h>
#include <functional>
#include "Log.hpp"
#include "LockGuard.hpp"
using namespace log_ns;
namespace The_Thread{
    using func_t = std::function<void(const std::string&)>;
    class Thread{
        public:
           void Excute(){
                //std::cout << _name << "  running" << std::endl;
                Log(DEBUG, "%s is running!!!\n", _name.c_str());
                _isrunning = true;
                _func(_name);
                pthread_cancel(_tid);
            }
        public:
            Thread(const std::string& name, func_t func)
            : _name(name)
            , _func(func)
            {
                //std::cout << _name << "  Create" << std::endl;
                Log(DEBUG, "%s Creat!!!\n", _name.c_str());
            }
            static void* ThreadRoutine(void* args){
                Thread* self = static_cast<Thread*>(args);
                self->Excute();
                return nullptr;
            }
            bool Start(){
                int n = ::pthread_create(&_tid, nullptr, ThreadRoutine, (void*)this);
                //std::cout << _name << "  Start" << std::endl;
                Log(DEBUG, "%s Start!!!\n", _name.c_str());
                if(n != 0)
                    return false;
                return true;
            }
            void Status(){
                if(_isrunning)
                    //std::cout << "running" << std::endl;
                    Log(DEBUG, "%s is running!!!\n", _name.c_str());
                else
                    //std::cout << "sleep" << std::endl;
                    Log(DEBUG, "%s is sleep!!!\n", _name.c_str());
            }
            std::string Getname(){
                return _name;
            }
            void Stop(){
                if(_isrunning)
                {
                    ::pthread_cancel(_tid);
                    _isrunning = false;
                    //std::cout << _name << "  Stop" << std::endl;
                    Log(DEBUG, "%s is stop!!!\n", _name.c_str());
                }
            }
            void Join(){
                    ::pthread_join(_tid, nullptr);
                     //std::cout << _name << "  Join" << std::endl;
                     Log(DEBUG, "%s is join!!!\n", _name.c_str());
            }
            ~Thread(){
                // Join();
                //std::cout << _name << "  Destory" << std::endl;
                Log(DEBUG, "%s is destory!!!\n", _name.c_str());
            }
            
        private:
            std::string _name;
            pthread_t _tid;
            bool _isrunning;
            func_t _func;
    };
}
